#include <iostream>
#include <string>
#include <stdexcept> // 用于抛出异常
using namespace std;

class Calculator {
public:
    int getResult (string oper) {
        if (oper == "+") {
            return m_Num1 + m_Num2;
        } else if(oper == "-") { 
            return m_Num1 - m_Num2;
        } else if(oper == "*") {
            return m_Num1 * m_Num2;
        // 可以添加一个除法的处理
        } else if(oper == "/") {
            // 需要判断除数是否为零
            if (m_Num2 == 0) {
                throw invalid_argument("Division by zero.");
            }
            return m_Num1 / m_Num2;
        }
        // 如果运算符不是以上任何一个，抛出异常或返回一个特殊值
        throw invalid_argument("Invalid operator.");
        // 如果想扩展功能，需要修改源码
        // 在真实开发当中 提倡一种开闭原则
        // 开闭原则：对扩展进行开放，对修改进行关闭
    }

    int m_Num1;
    int m_Num2;
};

// 利用多态实现计算器

// 实现计算器抽象类
class AbstractCalculator
{
public:
    virtual int getResult()
    {
        return 0;
    }

    int m_Num1;
    int m_Num2;
};

// 加法计算器类
class AddCalculator : public AbstractCalculator
{
public:
    int getResult()
    {
        return m_Num1 + m_Num2;
    }
};

// 减法计算器类
class SubCalculator : public AbstractCalculator
{
public:
    int getResult()
    {
        return m_Num1 - m_Num2;
    }
};

// 乘法计算器类
class MulCalculator : public AbstractCalculator
{
public:
    int getResult()
    {
        return m_Num1 * m_Num2;
    }
};

// 除法计算器类
class DivCalculator : public AbstractCalculator
{
public:
    int getResult()
    {
        if (m_Num2 == 0) {
            throw invalid_argument("Division by zero.");
        }
        return m_Num1 / m_Num2;
    }
};

void test01() 
{
    Calculator c;
    c.m_Num1 = 10;
    c.m_Num2 = 10;
    cout << c.m_Num1 << " + " << c.m_Num2 << " = " << c.getResult("+") << endl;
}

void test02()
{
    // 多态的使用条件
    // 父类的指针或引用指向子类对象
    // 加法运算
    AbstractCalculator * abc = new AddCalculator;
    abc->m_Num1 = 10;
    abc->m_Num2 = 10;
    cout << abc->m_Num1 << " + " << abc->m_Num2 << " = " << abc->getResult() <<endl;
    delete abc;    

    abc = new SubCalculator;
    abc->m_Num1 = 10;
    abc->m_Num2 = 10;
    cout << abc->m_Num1 << " - " << abc->m_Num2 << " = " << abc->getResult() <<endl;
    delete abc;

    abc = new MulCalculator;
    abc->m_Num1 = 10;
    abc->m_Num2 = 10;
    cout << abc->m_Num1 << " * " << abc->m_Num2 << " = " << abc->getResult() <<endl;
    delete abc;  

    abc = new DivCalculator;
    abc->m_Num1 = 10;
    abc->m_Num2 = 10;
    cout << abc->m_Num1 << " / " << abc->m_Num2 << " = " << abc->getResult() <<endl;
    delete abc;                               
}

int main() {
    try {
        // test01();
        test02();
    } catch (const invalid_argument& e) {
        cerr << "Error: " << e.what() << endl;
    }
    return 0;
}
